import logging
import json
import inspect
from flask import current_app


class BaseLogger:
    """
    基础日志器封装，提供通用的日志功能
    """
    
    def __init__(self, name=None, level=logging.INFO):
        """
        初始化基础日志器
        
        Args:
            name: 日志器名称，如果为None则自动获取调用者信息
            level: 日志级别
        """
        self.name = name or self._get_caller_name()
        self.level = level
        self._logger = None
        self._setup_logger()
    
    def _get_caller_name(self):
        """获取调用者的模块名"""
        frame = inspect.currentframe().f_back.f_back
        module_name = frame.f_globals.get('__name__', 'app')
        return module_name
    
    def _setup_logger(self):
        """设置日志器"""
        self._logger = logging.getLogger(self.name)
        self._logger.setLevel(self.level)
        
        # 如果在Flask应用上下文中，使用应用的处理器
        try:
            if current_app and current_app.logger.handlers:
                for handler in current_app.logger.handlers:
                    if handler not in self._logger.handlers:
                        self._logger.addHandler(handler)
            else:
                # 不在应用上下文中或没有处理器，使用默认处理器
                self._setup_default_handlers()
        except RuntimeError:
            # 不在应用上下文中，使用默认处理器
            self._setup_default_handlers()
    
    def _setup_default_handlers(self):
        """设置默认的日志处理器"""
        # 控制台处理器
        console_handler = logging.StreamHandler()
        console_handler.setLevel(self.level)
        formatter = logging.Formatter(
            '%(asctime)s - %(levelname)s - %(name)s - %(module)s - %(funcName)s - %(thread)d - %(threadName)s - %(process)d - %(message)s'
        )
        console_handler.setFormatter(formatter)
        self._logger.addHandler(console_handler)

    def _format_log(self, message, extra=None):
        """格式化日志内容"""
        if extra:
            return f"{message}\n{json.dumps(extra, ensure_ascii=False, indent=2)}"
        return message
    
    def _log(self, level, message, extra=None, auto_format=True, *args, **kwargs):
        """
        通用日志记录方法
        
        Args:
            level: 日志级别
            message: 日志消息
            extra: 额外信息
            auto_format: 是否自动格式化extra信息，默认True
            *args, **kwargs: 传递给logger的其他参数
        """
        if auto_format and extra:
            formatted_message = self._format_log(message, extra)
            self._logger.log(level, formatted_message, *args)
        else:
            self._logger.log(level, message, *args, extra=extra, **kwargs)
    
    def log_raw(self, level, message, *args, **kwargs):
        """
        记录原始日志，不进行额外格式化
        
        Args:
            level: 日志级别
            message: 日志消息
            *args, **kwargs: 传递给logger的其他参数
        """
        self._log(level, message, auto_format=False, *args, **kwargs)
    
    def info(self, message, extra=None, auto_format=True, *args, **kwargs):
        """
        记录INFO级别日志
        
        Args:
            message: 日志消息
            extra: 额外信息
            auto_format: 是否自动格式化extra信息，默认True
            *args, **kwargs: 其他参数
        """
        self._log(logging.INFO, message, extra, auto_format, *args, **kwargs)
    
    def debug(self, message, extra=None, auto_format=True, *args, **kwargs):
        """记录DEBUG级别日志"""
        self._log(logging.DEBUG, message, extra, auto_format, *args, **kwargs)
    
    def warning(self, message, extra=None, auto_format=True, *args, **kwargs):
        """记录WARNING级别日志"""
        self._log(logging.WARNING, message, extra, auto_format, *args, **kwargs)
    
    def error(self, message, extra=None, auto_format=True, *args, **kwargs):
        """记录ERROR级别日志"""
        self._log(logging.ERROR, message, extra, auto_format, *args, **kwargs)
    
    def critical(self, message, extra=None, auto_format=True, *args, **kwargs):
        """记录CRITICAL级别日志"""
        self._log(logging.CRITICAL, message, extra, auto_format, *args, **kwargs)
    
    def exception(self, message, extra=None, auto_format=True, *args, **kwargs):
        """记录异常信息（包含堆栈跟踪）"""
        kwargs['exc_info'] = True
        self._log(logging.ERROR, message, extra, auto_format, *args, **kwargs)